﻿// -----------------------------------------------------------------------
// <copyright file="EqualizerController.cs" company="Abyssalsoft">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace Metal.Player.Equalizer
{
    using System;
    using System.Collections.Generic;
    using System.Reflection;
    using System.Text;
    using Core.Player;
    using Metal.Config;

    /// <summary>
    /// Equalizer controller
    /// </summary>
    public class EqualizerController
    {
        #region Members

        /// <summary> The view used to communicate with the mask </summary>
        private static IEqualizerView view;

        /// <summary> Dummy object </summary>
        private object objSender;

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the EqualizerController class.
        /// </summary>
        /// <param name="iView">Interface to communicate with the mask</param>
        public EqualizerController(IEqualizerView iView)
        {
            view = iView;
            this.SubscribeToViewEvents();
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the interface to communicate with the mask
        /// </summary>
        internal static IEqualizerView View
        {
            get
            {
                return view;
            }

            set
            {
                view = value;
            }
        }

        #endregion

        #region Private methods

        /// <summary>
        /// Subscribe to events defined in the view
        /// </summary>
        private void SubscribeToViewEvents()
        {
            try
            {
                view.MaskLoad += new EventHandler(this.OnMaskLoad);
                view.MaskClose += new EventHandler(this.OnMaskClose);
                view.ControlAdded += new System.Windows.Forms.ControlEventHandler(this.OnControlAdded);

                Core.Player.Events.Instance.Play += new EventHandler(this.OnPlay);

                Core.Player.Settings.Instance.InitEqualizer();
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// This event occurs when the user change slider value
        /// </summary>
        /// <param name="sender">Object sender</param>
        /// <param name="e">Event args</param>
        private void OnSliderDrag(object sender, System.Windows.Forms.ScrollEventArgs e)
        {
            try
            {
                this.objSender = sender;
                Type thisType = typeof(EqualizerController);
                string strMethodName = ((Gui.Controls.MetalSlider)sender).Name;
                MethodInfo theMethod = thisType.GetMethod(strMethodName.Substring(0, strMethodName.Length - 1), BindingFlags.NonPublic | BindingFlags.Instance);
                object[] tags = new object[2];
                tags[0] = ((Gui.Controls.MetalSlider)sender).Tag;
                tags[1] = ((Gui.Controls.MetalSlider)sender).Value;
                if (theMethod != null)
                {
                    theMethod.Invoke(this, tags);
                }
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// This method is called via Reflection, when the user change equalizer values
        /// </summary>
        /// <param name="tag">The tag property containing the index of the scrollbar (band)</param>
        /// <param name="value">New value</param>
        private void BandEq(object tag, int value)
        {
            try
            {
                int eqIndex = Convert.ToInt32(tag);
                EqualizerLogic.Instance.BandArray[eqIndex] = value;
                Core.Player.Settings.Instance.SetEqualizer(eqIndex, value);
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        #endregion

        #region Mask events

        /// <summary>
        /// This method is called when the mask is loaded.
        /// </summary>
        /// <param name="sender">Object sender</param>
        /// <param name="e">Event arguments</param>
        private void OnMaskLoad(object sender, EventArgs e)
        {
            try
            {
                // Load settings
                EqualizerLogic.Instance.BandArray = new int[10];
                for (int i = 0; i < 10; i++)
                {
                    // Load last values from xml into array
                    EqualizerLogic.Instance.BandArray[i] = Metal.Config.Settings.Instance.GetValue("LastSettings.Equalizer.Parameters.Band" + i, 50);

                    // Apply values
                    this.BandEq(i, EqualizerLogic.Instance.BandArray[i]);
                }

                view.Band = EqualizerLogic.Instance.BandArray;
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// This method is called when the mask is closed.
        /// </summary>
        /// <param name="sender">Object sender</param>
        /// <param name="e">Event arguments</param>
        private void OnMaskClose(object sender, EventArgs e)
        {
            try
            {
                string playerStyle = Metal.Config.Settings.Instance.GetValue("LastSettings.MainFormStyle", "Audio");

                // Save settings
                for (int i = 0; i < 10; i++)
                {
                    Metal.Config.Settings.Instance.SetValue("LastSettings.Equalizer.Parameters.Band" + i, EqualizerLogic.Instance.BandArray[i]);
                }
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// This method is called when a control is added on the mask
        /// </summary>
        /// <param name="sender">Object sender</param>
        /// <param name="e">Event arguments</param>
        private void OnControlAdded(object sender, System.Windows.Forms.ControlEventArgs e)
        {
            try
            {
                if (e.Control.GetType() == typeof(Gui.Controls.MetalSlider))
                {
                    (e.Control as Gui.Controls.MetalSlider).Scroll += new System.Windows.Forms.ScrollEventHandler(this.OnSliderDrag);
                }
                else if (e.Control.GetType() == typeof(Gui.Controls.MetalPanel))
                {
                    e.Control.ControlAdded += new System.Windows.Forms.ControlEventHandler(this.OnControlAdded);
                }
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        #endregion

        #region Player events

        /// <summary>
        /// This event occurs when a new playback is started
        /// </summary>
        /// <param name="sender">Object sender</param>
        /// <param name="e">Event args</param>
        private void OnPlay(object sender, EventArgs e)
        {
            try
            {
                if (MediaInfo.CurrentFile != Helper.FileTypeEnum.LocalAudio || MediaInfo.CurrentFile != Helper.FileTypeEnum.InternetAudioStream)
                {
                    return;
                }

                for (int i = 0; i < 10; i++)
                {
                    Core.Player.Settings.Instance.SetEqualizer(i, EqualizerLogic.Instance.BandArray[i]);
                }
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        #endregion
    }
}
